package de.velvettear.squirrel.kernel;

import java.util.HashMap;
import java.util.UUID;
import java.util.Vector;

import android.content.ContentValues;
import android.database.Cursor;
import android.util.Log;
import de.velvettear.squirrel.database.Column;
import de.velvettear.squirrel.database.Column.ColumnDataType;
import de.velvettear.squirrel.util.TimeHelper;

public class Base implements Cloneable {

	public final static String TABLENAME = "Base";
	
	public int m_nID;
	public String m_sGUID = "";
	public String m_sName = "";
	public String m_sComment = "";
	public String m_sCreateDate = "";
	public String m_sChangeDate = "";
	
	public Base() {
		m_sGUID = UUID.randomUUID().toString();
	}
	
	public String getTableName() {
		return TABLENAME;
	}
	
	public HashMap<String,Object> getData() {
		HashMap<String, Object> retVal = new HashMap<String, Object>();
		retVal.put("m_nID", 		this.m_nID);
		retVal.put("m_sGUID", 		this.m_sGUID);
		retVal.put("m_sComment",	this.m_sComment);
		retVal.put("m_sName",		this.m_sName);
		retVal.put("m_sCreateDate", this.m_sCreateDate);
		retVal.put("m_sChangeDate", this.m_sChangeDate);
		return retVal;  
	}
	
	public void setData(Cursor c) {		   
		this.m_nID 				= c.getInt(c.getColumnIndex("m_nID"));
		this.m_sGUID 			= c.getString(c.getColumnIndex("m_sGUID"));
		this.m_sComment			= c.getString(c.getColumnIndex("m_sComment"));
		this.m_sName			= c.getString(c.getColumnIndex("m_sName"));
		this.m_sCreateDate		= c.getString(c.getColumnIndex("m_sCreateDate"));
		this.m_sChangeDate		= c.getString(c.getColumnIndex("m_sChangeDate"));
	}
	
	public static Vector<Column> getColumnConfig() {                          
		Vector<Column> retVal = new Vector<Column>();                
                                                                                
		retVal.add(new Column("m_nID",			 1000, true, ColumnDataType.sql_integer));	
		retVal.add(new Column("m_sGUID", 		 1000, false, ColumnDataType.sql_varchar));
		retVal.add(new Column("m_sComment",		 4000, false, ColumnDataType.sql_varchar));	
		retVal.add(new Column("m_sName",		 4000, false, ColumnDataType.sql_varchar));	
		retVal.add(new Column("m_sCreateDate",	 4000, false, ColumnDataType.sql_varchar));	
		retVal.add(new Column("m_sChangeDate", 	 4000, false, ColumnDataType.sql_varchar));	
		
		return retVal;																   
	}
	
	public boolean isValid() {
		if (this.m_nID > 0) {
			return true;
		}
		
		return false;
	}
	
	public boolean store() {
		if (exists()) {
			return update();
		} else {
			return insert();
		}
	}
	
	private int getNextID(String tableName) {
		Log.i("getNextID()", "BEGIN");
		
		int nextID = 0;
		String query = "SELECT MAX(m_nID) FROM " + tableName;
		
		try {
			Cursor cursor = Statics.DATABASEHELPER.getReadableDatabase().rawQuery(query, null);
			cursor.moveToFirst();
			nextID = cursor.getInt(0) + 1;
			cursor.close();
		} catch (Exception e) {
			if (e.getMessage() != null) {
				Log.e("getNextID()", e.getMessage());
			}
		}
		
		Log.i("getNextID()", "END");
		return nextID;
	}
	
	public boolean exists() {    
		Log.i("exists()", "BEGIN");
		
	    String countQuery = "SELECT  * FROM " + getTableName() + " WHERE m_sGUID = '" + this.m_sGUID.toString() +"'";

		try {	
    		Cursor cursor = Statics.DATABASEHELPER.getReadableDatabase().rawQuery(countQuery, null);
   	        int counter = cursor.getCount();
   	        if (counter > 0) {
   	        	cursor.moveToFirst();
   	        	this.m_nID 	= cursor.getInt(cursor.getColumnIndex("m_nID"));   	         	
   	        }
   	        cursor.close();
    	
    		if (counter > 0) {
    			return true;
    		}
    	} catch (Exception e) {
    		if (e.getMessage() != null) {
    			Log.e("exists()", e.getMessage());
    		}
    	} 
		
		if (this.m_nID != 0) {
			countQuery = "SELECT  * FROM " + getTableName() + " WHERE m_nID = " + this.m_nID;
			try {	
				Cursor cursor = Statics.DATABASEHELPER.getReadableDatabase().rawQuery(countQuery, null);
				int counter = cursor.getCount();
				cursor.close();
				if (counter > 0) {
					return true;
				}			
			} catch (Exception e) {
				if (e.getMessage() != null) {
					Log.e("exists()", e.getMessage());
				}
			} 			
		}
			
		Log.i("exists()", "END");
		return false;
	}
	
	protected boolean insert() {
		Log.i("insert()", "BEGIN");
		
		this.m_nID = getNextID(getTableName());
		
		ContentValues values = new ContentValues();
		   
		HashMap<String, Object> tmpData = getData();
		for (String sColumn : tmpData.keySet()) {
			if (tmpData.get(sColumn) instanceof Integer) {
				values.put(sColumn, (Integer) tmpData.get(sColumn));
			} else if (tmpData.get(sColumn) instanceof String) {
				values.put(sColumn, (String) tmpData.get(sColumn));
			}
		}
		
		try {	
			Statics.DATABASEHELPER.getWritableDatabase().insert(getTableName(), null, values);
		} catch (Exception e) {
			if (e.getMessage() != null) {
				Log.e("exists()", e.getMessage());
			}
			return false;
		} 
		
		Log.i("insert()", "END");
		return true;
	   }
	
	protected boolean update() {	
		Log.i("update()", "BEGIN");
		
		ContentValues values = new ContentValues();		   
		HashMap<String, Object> data = getData();
		for (String m_sColumn : data.keySet()) {
			if (!m_sColumn.equals("m_nID")) {
				if (data.get(m_sColumn) instanceof Integer) {
					values.put(m_sColumn,(Integer) data.get(m_sColumn));
				} else if (data.get(m_sColumn) instanceof String) {
					values.put(m_sColumn,(String) data.get(m_sColumn));
				}
			}
		}

		try {	
			Statics.DATABASEHELPER.getWritableDatabase().update(getTableName() , values, "m_nID = ?", new String[] {String.valueOf(this.m_nID)});
		} catch (Exception e) {
			if (e.getMessage() != null) {
				Log.e("exists()", e.getMessage());
			}
			return false;
		} 
		
		Log.i("update()", "END");
		return true;
	}
		
	public Vector getObjectByID(String m_nID) {
		return select("m_nID = " + m_nID, null, false);
	}
	
	public Vector getObjectByGUID(String m_sGUID) {
		return select("m_sGUID = " + m_sGUID, null, false);
	}
	
	public Vector select(String m_sWhereClause, String m_sOrderBy, boolean m_bDescending) {
		Log.i("select()", "BEGIN");
		
		Vector retVal = new Vector();
		   
		String selectQuery = "SELECT * FROM " + getTableName(); 
		if (m_sWhereClause != null && m_sWhereClause.length() > 0) {
			selectQuery += " WHERE " + m_sWhereClause;	
		}
		if (m_sOrderBy != null && m_sOrderBy.length() > 0) {
			selectQuery += " ORDER BY " + m_sOrderBy;	  
		}
		if (m_bDescending) {
			selectQuery += " DESC";
		}
		
		try {	
			Cursor cursor = Statics.DATABASEHELPER.getReadableDatabase().rawQuery(selectQuery, null);
			while (cursor.moveToNext()) {
				setData(cursor);
				retVal.add(this.clone());
			}	    
			cursor.close();
		} catch (Exception e) {
			if (e.getMessage() != null) {
				Log.e("exists()", e.getMessage());
			}
		} 
			
		Log.i("select()", "END");
		return retVal;
	}
		
	public void delete() {
		try {
			Statics.DATABASEHELPER.getWritableDatabase().execSQL("DELETE FROM " + getTableName() +	" WHERE m_nID = " + this.m_nID);
		} catch (Exception e) {
			if (e.getMessage() != null) {
				Log.e("exists()", e.getMessage());
			}
		}
	}
	
	public void deleteAll() {
		try {
			Statics.DATABASEHELPER.getWritableDatabase().execSQL("DELETE FROM " + getTableName());
		} catch (Exception e) {
			if (e.getMessage() != null) {
				Log.e("exists()", e.getMessage());
			}
		}
	}
	
}
